package com.rpframework.utils

import com.alibaba.fastjson.JSONObject
import net.sf.json.xml.XMLSerializer
import org.apache.xml.serialize.OutputFormat
import org.w3c.dom.Document
import org.xml.sax.InputSource
import org.xml.sax.SAXException
import java.io.IOException
import java.io.StringReader
import java.io.StringWriter
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException
import org.apache.xml.serialize.XMLSerializer as apacheXMLSerializer


/**
 * XML工具类
 * Created by lx178 on 2016/12/15.
 */
object XmlUtil {
    val escapePro = "[CDATA:"
    var escapeSuf = "]"

    /**
     * 判断内容[content]是否转义，转义即去除转义[escapePro][escapeSuf]
     */
    fun escapeContent(content: String): String {
        var result = content
        val escape = content.startsWith(escapePro)
        if (escape) {
            try {
                result = content.substring(0, escapePro.length)
                result = result.substring(escapePro.length - escapeSuf.length,
                        escapePro.length)
            } catch (e: IndexOutOfBoundsException) {
                result = content
            }
        }
        return result
    }

    /**
     * XML数据转PO对象
     */
    fun <T> xml2Po(xml: String, type: Class<T>): T {
        return JSONObject.parseObject(xml2JSON(xml), type)
    }

    /**
     * XML转成JSON
     */
    fun xml2JSON(xml: String): String {
        return XMLSerializer().read(xml).toString()
    }

    fun format(unformattedXml: String): String {
        try {
            val document = parseXmlFile(unformattedXml)
            val format = OutputFormat(document)
            format.lineWidth = 65
            format.indenting = true
            format.indent = 2
            val out = StringWriter()
            val serializer = apacheXMLSerializer(out, format)
            serializer.serialize(document)
            return out.toString()
        } catch (e: IOException) {
            throw RuntimeException(e)
        }

    }

    private fun parseXmlFile(`in`: String): Document {
        try {
            val dbf = DocumentBuilderFactory.newInstance()
            val db = dbf.newDocumentBuilder()
            val `is` = InputSource(StringReader(`in`))
            return db.parse(`is`)
        } catch (e: ParserConfigurationException) {
            throw RuntimeException(e)
        } catch (e: SAXException) {
            throw RuntimeException(e)
        } catch (e: IOException) {
            throw RuntimeException(e)
        }

    }

}
